#pragma once

#include <iostream>
#include <cstdint>
#include <sys/epoll.h>
#include <functional>
#include <unistd.h>

#define MAX_EVENTS 1024

class EventLoop {
public:

    friend class Poller;
/**
 * EventLoop类的构造函数
 * 用于创建epoll实例，用于I/O事件的多路复用
 */
    EventLoop(): epfd(-1) {  // 初始化epfd成员变量为-1
        epfd = epoll_create1(0);
        if(epfd == -1) {
            std::cerr << "epoll_create1 failed" << std::endl;  // 输出错误信息
            exit(EXIT_FAILURE)  // 如果创建失败，退出程序
        }
    }

    ~EventLoop() {
        if(epfd != -1) {
            close(epfd);
        }
    }

private:
    void AddEvent(int fd, uint32_t events, void* ptr) {
        struct epoll_event ev;
        ev.events = events;
        ev.data.ptr = ptr;
        if(epoll_ctl(epfd, EPOLL_CTL_ADD, fd, &ev) == -1) {
            std::cerr << "epoll_ctl failed" << std::endl;
        }
    }

    void ModEvent(int fd, uint32_t events, void* ptr) {
        struct epoll_event ev;
        ev.events = events;
        ev.data.ptr = ptr;
        if(epoll_ctl(epfd, EPOLL_CTL_MOD, fd, &ev) == -1) {
            std::cerr << "epoll_ctl failed" << std::endl;
        }
    }

    void DelEvent(int fd) {
        if(epoll_ctl(epfd, EPOLL_CTL_DEL, fd, &ev) == -1) {
            std::cerr << "epoll_ctl failed" << std::endl;
        }
    }
    
    void Run() {
        struct epoll_event events[MAX_EVENTS];
        while(true) {
            int nfds = epoll_wait(epfd, events, MAX_EVENTS, -1);
            if(nfds == -1) {
                if(errno == EINTR) {
                    continue;
                }
                std::cerr << "epoll_wait failed" << std::endl;
                break;
            }
            for(int i = 0; i < nfds; ++i {
                if(events[i].events & EPOLLIN) {
                    auto handler = static_cast<std::function<void(int)> *>(events[i].data.ptr);
                    (*handler)(events[i].events);
                }
            }
        }
    }
private:
    int epfd;
};